#include "disk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <errno.h>

static int disk_fd = -1;
static void *disk_base = NULL;

int disk_init() {
    // 打开或创建磁盘文件
    disk_fd = open(DISK_FILE, O_RDWR | O_CREAT, 0666);
    if (disk_fd < 0) {
        perror("open");
        return -1;
    }

    // 检查文件大小
    struct stat st;
    if (fstat(disk_fd, &st) < 0) {
        perror("fstat");
        return -1;
    }

    if (st.st_size < DISK_SIZE) {
        if (ftruncate(disk_fd, DISK_SIZE) < 0) {
            perror("ftruncate");
            return -1;
        }
    }

    // 映射磁盘文件
    disk_base = mmap(NULL, DISK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, disk_fd, 0);
    if (disk_base == MAP_FAILED) {
        perror("mmap");
        return -1;
    }

    return 0;
}

void disk_close() {
    if (disk_base) {
        munmap(disk_base, DISK_SIZE);
        disk_base = NULL;
    }
    if (disk_fd >= 0) {
        close(disk_fd);
        disk_fd = -1;
    }
}

void *disk_get_base() {
    return disk_base;
}

int read_block(void *buf, size_t block_num) {
    if (block_num * BLOCK_SIZE >= DISK_SIZE) return -1;
    memcpy(buf, disk_base + block_num * BLOCK_SIZE, BLOCK_SIZE);
    return 0;
}

int write_block(const void *buf, size_t block_num) {
    if (block_num * BLOCK_SIZE >= DISK_SIZE) return -1;
    memcpy(disk_base + block_num * BLOCK_SIZE, buf, BLOCK_SIZE);
    return 0;
}
